home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
mint
/
lib
/
mntlib44.zoo
/
mntlib
/
sigactio.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-09-22
|
5KB
|
236 lines
/* sigaction() and sigset functions for MiNT; placed in the public domain */
#include <errno.h>
#include <osbind.h>
#include <mintbind.h>
#include <signal.h>
/* vector of signal handlers (for TOS, or for MiNT with -mshort) */
extern __Sigfunc _sig_handler[__NSIG];
#ifdef __MSHORT__
typedef void __CDECL (*__KerSigfunc) __PROTO((long, long));
__EXTERN void __CDECL _trampoline __PROTO((long sig, long code));
#else
typedef void __CDECL (*__KerSigfunc) __PROTO((int));
#endif
int
sigaction(sig, act, oact)
int sig;
const struct sigaction *act;
struct sigaction *oact;
{
long r;
extern int __mint;
__Sigfunc oldfunc;
if (__mint >= 95) {
struct ksigact {
__KerSigfunc sa_handler; /* pointer to signal handler */
long sa_mask; /* additional signals masked during delivery */
short sa_flags; /* signal specific flags, kernel */
} kact, koact;
if (sig < 0 || sig >= __NSIG) {
errno = ERANGE;
return -1;
}
#ifdef __MSHORT__
/* NOTE: MiNT passes 32 bit numbers for signals, so we want our
* own signal dispatcher to switch these to 16 bit ints
*/
oldfunc = _sig_handler[sig];
#endif
if (act) {
kact.sa_handler = (__KerSigfunc) act->sa_handler;
kact.sa_mask = act->sa_mask.__sigset_data[0];
kact.sa_flags = (short) act->sa_flags;
#ifdef __MSHORT__
_sig_handler[sig] = (__Sigfunc)kact.sa_handler;
if (_sig_handler[sig] != SIG_DFL && _sig_handler[sig] != SIG_IGN) {
kact.sa_handler = _trampoline;
}
#endif
}
r = Psigaction(sig, (act ? &kact : 0L), (oact ? &koact : 0L));
if (r < 0) {
errno = (int) -r;
return -1;
}
if (oact) {
oact->sa_mask.__sigset_data[0] = koact.sa_mask;
oact->sa_flags = (int) koact.sa_flags;
#ifdef __MSHORT__
oact->sa_handler =
((koact.sa_handler == (__KerSigfunc) _trampoline)
? oldfunc
: (__Sigfunc) koact.sa_handler);
#else
oact->sa_handler = (__Sigfunc) koact.sa_handler;
#endif
}
}
else {
if (act)
oldfunc = signal(sig, act->sa_handler);
else {
long omask;
omask = sigblock(sig);
oldfunc = signal(sig, SIG_DFL);
signal(sig, oldfunc); /* need to put it back */
sigsetmask(omask); /* may remask sig (this is what we want) */
}
if (oldfunc == SIG_ERR)
return -1;
if (oact) {
oact->sa_handler = oldfunc;
/* we could do something useful with sa_mask when __mint */
oact->sa_flags = 0;
oact->sa_mask.__sigset_data[0] = 0;
}
}
return 0;
}
int
sigaddset(set, signo)
sigset_t *set;
int signo;
{
int idx;
int pos;
if ((!set) || (signo >= __NSIG)) {
errno = EINVAL;
return -1;
}
idx = _SIGSET_INDEX(signo);
pos = _SIGSET_BITPOS(signo);
set->__sigset_data[idx] |= sigmask(pos);
return 0;
}
int
sigdelset(set, signo)
sigset_t *set;
int signo;
{
int idx;
int pos;
if ((!set) || (signo >= __NSIG)) {
errno = EINVAL;
return -1;
}
idx = _SIGSET_INDEX(signo);
pos = _SIGSET_BITPOS(signo);
set->__sigset_data[idx] &= ~(sigmask(pos));
return 0;
}
int
sigemptyset(set)
sigset_t *set;
{
int idx;
if (!set) {
errno = EINVAL;
return -1;
}
for (idx = _SIGSET_MAX_INDEX; idx >= 0; idx--) {
set->__sigset_data[idx] = 0UL;
}
return 0;
}
int
sigfillset(set)
sigset_t *set;
{
int idx;
if (!set) {
errno = EINVAL;
return -1;
}
for (idx = _SIGSET_MAX_INDEX; idx >= 0; idx--) {
set->__sigset_data[idx] = ~0UL;
}
return 0;
}
int
sigismember(set, signo)
sigset_t *set;
int signo;
{
int idx;
int pos;
if ((!set) || (signo >= __NSIG)) {
errno = EINVAL;
return -1;
}
idx = _SIGSET_INDEX(signo);
pos = _SIGSET_BITPOS(signo);
return (set->__sigset_data[idx] & sigmask(pos)) ? 1 : 0;
}
int
sigpending(set)
sigset_t *set;
{
if (!set) {
errno = EINVAL;
return -1;
}
(void) sigemptyset(set);
set->__sigset_data[0] = Psigpending();
return 0;
}
int
sigprocmask(how, set, oset)
int how;
const sigset_t *set;
sigset_t *oset;
{
int rv = 0;
long omask = 0L;
if (!set) {
errno = EINVAL;
return -1;
}
switch (how) {
case SIG_BLOCK:
omask = Psigblock(set->__sigset_data[0]);
break;
case SIG_UNBLOCK:
omask = Psigblock(0L);
(void) Psigsetmask(omask & ~(set->__sigset_data[0]));
break;
case SIG_SETMASK:
omask = Psigsetmask(set->__sigset_data[0]);
break;
default:
errno = EINVAL;
rv = -1;
}
if (oset) oset->__sigset_data[0] = omask;
return rv;
}
int
sigsuspend(signalmask)
const sigset_t *signalmask;
{
Psigpause(signalmask->__sigset_data[0]);
errno = EINTR;
return -1;
}